//
// Created on 2025/7/2.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
// 生产者-消费者模型实现 
// 模型缓冲队列
#ifndef MultiThreads_ProducerConsumer_H
#define MultiThreads_ProducerConsumer_H


#include <string>
#include <queue>
#include <mutex>
#include <condition_variable>


using namespace std;
// Principles of the producer-consumer model: Use buffer zones to balance the rate between production and consumption.
// Synchronization relationship 1: When the buffer is full, the producer needs to be blocked and wait. When a product
// pops up the buffer, the producer needs to be woken up for consumption. Synchronization relationship 2: When the
// buffer is empty, the consumer needs to be blocked and waited. When a product enters the buffer, the consumer needs to
// be woken up for consumption.
class ProducerConsumerQueue {
public:
    // constructor
    ProducerConsumerQueue() {}
    ProducerConsumerQueue(int queueSize) : m_maxSize(queueSize) {}
    // producer enqueue operation
    void PutElement(string element);
    // consumer dequeue operation
    string TakeElement();
private:
    // check whether the buffer queue is full
    bool isFull() { return (m_queue.size() == m_maxSize); }
    // check whether the buffer queue is empty
    bool isEmpty() { return m_queue.empty(); }
private:
    queue<string> m_queue{};         // buffer queue
    int m_maxSize{};                 // buffer queue capacity
    mutex m_mutex{};                 // the mutex is used to protect data consistency
    condition_variable m_notEmpty{}; // condition variable, which is used to indicate whether the buffer queue is empty
    condition_variable m_notFull{};  // condition variable, which is used to indicate whether the buffer queue is full
};
#endif // MultiThreads_ProducerConsumer_H
